<!--
 * @Author: zhangyonggui
 * @Date: 2023-10-12 10:44:50
 * @LastEditors: zhangyonggui
 * @LastEditTime: 2023-10-25 16:58:22
 * @Descripttion: 
-->
<template>
  <div id="graphContainer" class="graph-wrap" ref="parentRoot">
    <GraphToolbar :graph="graph" :changeSize="changeSize" :parentRoot="parentRoot"></GraphToolbar>

    <div v-if="graphData?.nodes?.length" id="graph-container"></div>
    <noData v-else></noData>
  </div>
</template>
<script lang="ts" setup>
import G6 from '@antv/g6';
import GraphToolbar from './Toolbar.vue';
import {
  defineProps,
  onMounted,
  onUnmounted,
  ref,
  reactive,
} from 'vue';
import { useStore } from 'vuex';
const store = useStore();
const props = defineProps({
  rowList: {
    type: Object,
    default: () => {
      return {};
    },
  },
  changeSize:{
    type:Function
  } 
});
const parentRoot = ref<any>(null);
const graph = ref<any>(null);
let graphData = reactive({
  edges: [],
  nodes: [],
});
const searchContent = reactive({
  keyword: '',
  vertexLabel: '',
  pageNumber: 1,
  pageSize: 100,
});
const canvasWidth = ref<any>('');
const canvasHeight = ref<any>('');
onMounted(async () => {
  searchContent.keyword = props.rowList.assetId;
  searchContent.vertexLabel = props.rowList.assetType;
 const graphContainer : any=document.getElementById('graphContainer')
  canvasWidth.value = graphContainer.clientWidth;
  canvasHeight.value = graphContainer.clientHeight;
  await getGraphData();
  initG6(graphContainer);
  window.addEventListener('resize', handleWindowResize);
});
onUnmounted(() => {
  window.removeEventListener('resize', handleWindowResize);
});
const initG6 = (graphContainer) => {

  
  // 获取图容器的 DOM 元素
  const graphContainers = graphContainer;
  const graphs = new G6.Graph({
    container: graphContainers,
    width: canvasWidth.value,
    height: canvasHeight.value,
    layout: {
      type: 'force',
      preventOverlap: true,
      linkDistance: (d) => {
        if (d.source.level === 1) {
          return 200;
        }
        return 100;
      },
      nodeStrength: (d) => {
        if (d.level === 2 || d.level === 3) {
          return -500;
        }
        return -100;
      },
      edgeStrength: (d) => {
        // console.log(d, 1111)
        if (d.source.level === 1) {
          return 0.8;
        }
        if (d.source.level === 2) {
          return 0.4;
        }
        return 0.2;
      },
      nodeSpacing: (d) => {
        // console.log(d, 1111)
        if (d.level === 1) {
          return 10;
        }
        if (d.level === 2) {
          return 5;
        }
        return 2;
      },
    },
    defaultNode: {
      //color: 'red',
      labelCfg: {
        position: 'bottom',
        style: {
          fill: 'rgba(38, 114, 192, 1)',
          fontSize: 20,
        },
      },
    },
    defaultEdge: {
      type: 'line',
      style: {
        opacity: 1,
        stroke: '#516C83',
        lineWidth: 1,
        endArrow: {
          fill: '#516C83',
          path: G6.Arrow.triangle(5, 20, 25),
          d: 25,
        },
      },
      labelCfg: {
        autoRotate: true,
        refY: 0,
        style: {
          // stroke: '#FAFAFC',
          fill: '#9CA2B0',
          fontSize: 10,
          // lineWidth: 10,
          opacity: 1,
        },
      },
    },
    edgeStateStyles: {
      hover: {
        endArrow: {
          fill: '#2B8AFF',
          path: G6.Arrow.triangle(5, 5, 25),
          d: 20,
        },
        opacity: 1,
        lineWidth: 2,
        stroke: '#2B8AFF',
      },
    },

    modes: {
      default: ['drag-canvas'],
    },
  });

  graph.value = graphs;
  graphs.data(graphData);
  graphs.render();

  graphs.on('node:dragstart', function (e) {
    graphs.layout();
    refreshDragedNodePosition(e);
  });
  graphs.on('node:drag', function (e) {
    refreshDragedNodePosition(e);
  });
  graphs.on('node:dragend', function (e:any) {
    e.item.get('model').fx = null;
    e.item.get('model').fy = null;
  });

  function refreshDragedNodePosition(e) {
    const model = e.item.get('model');
    model.fx = e.x;
    model.fy = e.y;
  }
  // 解决g6debug
  graphs.get('canvas').set('localRefresh', false);
};
const getGraphData = async () => {
  const { code, data } = await store.dispatch(
    'detail/getRelationships',
    searchContent,
  );
  if (code === 0) {
    if (!data) {
      graphData = {
        edges: [],
        nodes: [],
      };
      return;
    }

    data.edges =
      data.edges?.map((el) => {
        return {
          ...el,
        };
      }) || [];

    data.nodes =
      data.nodes?.map((el) => {
        let gradient = 'vertexGradient';
        let icon = {
          text: '\uE90B',
          show: true,
        };
        let label = el.label;
        if (el.level === 1) {
          // 顶级
          gradient = 'vertexGradient';
        } else if (el.level === 2) {
          gradient = 'typeGradient';
          label = `${el.label}(${el.properties.count})`;
        } else if (el.level === 3) {
          gradient = 'subordinateGradient';
        }

        return {
          ...el,
          label,
          type: 'bg-gradients-node', // 这里的 type 应该与注册的节点名称匹配
          gradient: gradient,
          shapeType: 'circle',
          icon,
        };
      }) || [];
    graphData = data;
  }
};
const changeSize = async () => {
  const graphContainer: any = document.getElementById('graphContainer');
  if (graphContainer && graph.value) {
    canvasWidth.value = graphContainer.clientWidth;
    canvasHeight.value = graphContainer.clientHeight;
    graph.value.changeSize(canvasWidth.value, canvasHeight.value);
  }
};
const handleWindowResize = () => {
  if (!graph.value || graph.value.get('destroyed')) return;
  changeSize();
};
</script>

<style lang="scss" scoped>
.graph-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: $-white;
}
</style>
